package test;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.LinkedHashMap;
import java.util.Map;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;

public class SWTView{
    private static Shell      shell;
    private static Text       text;
    private static Button     button;
    private static SWTView    view = new SWTView();
    private static DBFactory  db;
    private static Color      bgcolor;
    private static CTabFolder folder;
    private static Tree       tree;

    public static void main(String[] args) throws Exception{

        Display display = new Display();
        bgcolor = display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);
        shell = new Shell(display);
        shell.setText("MyDBExplorer");
        shell.setSize(1500, 1300);
        shell.pack();
        GridLayout layout = new GridLayout(3, true);
        shell.setLayout(layout);
        tree = new Tree(shell, SWT.BORDER);
        tree.addListener(SWT.MouseDoubleClick, new Listener(){
            public void handleEvent(Event event){
                Point point = new Point(event.x, event.y);
                TreeItem item = tree.getItem(point);
                if(item != null){
                    TreeItem item2 = item.getParentItem();
                    if(item2 != null){
                        if("Tables".equals(item2.getText())
                            || "Views".equals(item2.getText())){
                            text.setText("select t.* from " + item.getText()
                                + " t");
                            view.doJob();
                        }
                    }
                }
            }
        });
        {
            GridData gridData = new GridData(GridData.FILL_BOTH);
            gridData.verticalSpan = 3;
            tree.setLayoutData(gridData);
        }
        text = new Text(shell, SWT.MULTI | SWT.BORDER);
        {
            GridData gridData = new GridData(GridData.FILL_BOTH);
            gridData.horizontalSpan = 2;
            text.setLayoutData(gridData);
        }
        button = new Button(shell, SWT.NONE);
        button.setText("Execute");
        {
            GridData gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
            button.setLayoutData(gridData);
        }
        button.addSelectionListener(new SelectionAdapter(){
            public void widgetSelected(SelectionEvent event){
                view.doJob();
            }
        });
        folder = new CTabFolder(shell, SWT.BORDER);
        {
            GridData gridData = new GridData(GridData.FILL_BOTH);
            gridData.horizontalSpan = 2;
            folder.setLayoutData(gridData);
        }
        view.doFirst();
        shell.pack();
        shell.open();
        while(!shell.isDisposed()){
            if(!display.readAndDispatch())
                display.sleep();
        }
        display.dispose();
    }

    private void doFirst() throws Exception{
        db = new DBFactory("lib/derby.jar",
            "org.apache.derby.jdbc.EmbeddedDriver",
            "jdbc:derby:derby.db;create=true");

        for(TreeItem item: tree.getItems()){
            item.dispose();
        }
        ResultSet set;
        Map<String, TreeItem> iSchemas = new LinkedHashMap<String, TreeItem>();
        TreeItem iSchema = new TreeItem(tree, 0);
        iSchema.setText("Schemas");
        set = db.getConnection().getMetaData().getSchemas();
        while(set.next()){
            TreeItem item;
            item = new TreeItem(iSchema, 0);
            item.setText(set.getString("TABLE_SCHEM"));
            iSchemas.put(item.getText(), item);
        }
        set.close();
        TreeItem iTables = new TreeItem(tree, 0);
        iTables.setText("Tables");
        TreeItem iViews = new TreeItem(tree, 0);
        iViews.setText("Views");
        set = db.getConnection().getMetaData().getTables(null, null, "%",
            new String[]{"TABLE", "VIEW"});
        while(set.next()){
            TreeItem item = null;
            TreeItem x = null;
            if(set.getString("TABLE_TYPE").equals("VIEW")){
                item = new TreeItem(iViews, 0);
                x = new TreeItem(getItem(iSchemas.get(set
                    .getString("TABLE_SCHEM")), "Views"), 0);
            }else
                if(set.getString("TABLE_TYPE").equals("TABLE")){
                    item = new TreeItem(iTables, 0);
                    x = new TreeItem(getItem(iSchemas.get(set
                        .getString("TABLE_SCHEM")), "Tables"), 0);
                }
            if(item != null){
                item.setText(set.getString("TABLE_SCHEM") + "."
                    + set.getString("TABLE_NAME"));
                x.setText(set.getString("TABLE_NAME"));
            }
        }
        set.close();
    }

    private TreeItem getItem(TreeItem parent, String name){
        for(TreeItem o: parent.getItems()){
            if(o.getText().equals(name))
                return o;
        }
        TreeItem x = new TreeItem(parent, 0);
        x.setText(name);
        return x;
    }

    private void doJob(){
        CTabItem iFolder = new CTabItem(folder, SWT.CLOSE);
        Table table = new Table(folder, SWT.MULTI | SWT.BORDER
            | SWT.FULL_SELECTION);
        iFolder.setControl(table);
        iFolder.setText(text.getText());
        table.setLinesVisible(true);
        table.setHeaderVisible(true);
        table.setItemCount(0);
        for(TableColumn col: table.getColumns()){
            col.dispose();
        }
        try{
            PreparedStatement st = db.prepareStatement(text.getText());
            if(st.execute()){
                ResultSet rs = st.getResultSet();
                ResultSetMetaData rsmd = rs.getMetaData();
                int numColumns = rsmd.getColumnCount();
                for(int i = 0; i < numColumns; i++){
                    TableColumn column = new TableColumn(table, SWT.NONE);
                    column.setText(rsmd.getColumnName(i + 1));
                }
                int k = 0;
                while(rs.next()){
                    k++;
                    TableItem item = new TableItem(table, SWT.NONE);
                    if(k % 2 == 0)
                        item.setBackground(bgcolor);
                    for(int i = 0; i < numColumns; i++){
                        Object o = rs.getObject(i + 1);
                        if(o != null)
                            item.setText(i, o.toString());
                    }
                }
                rs.close();
                for(int i = 0; i < numColumns; i++){
                    table.getColumn(i).pack();
                }
            }else{
                TableColumn column = new TableColumn(table, SWT.NONE);
                column.setText("Message:");
                TableItem item = new TableItem(table, SWT.NONE);
                item.setText("Done");
                table.getColumn(0).pack();
            }
            st.close();
        }catch(Exception e){
            // TODO: handle exception
        }
    }
}
